using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;

namespace FEZFirmwareUpdater
{
    public static class NativeHelper
    {
        [StructLayout(LayoutKind.Sequential)]
        private struct Margins
        {
            public int cxLeftWidth;      // width of left border that retains its size
            public int cxRightWidth;     // width of right border that retains its size
            public int cyTopHeight;      // height of top border that retains its size
            public int cyBottomHeight;   // height of bottom border that retains its size
        };

        [DllImport("DwmApi.dll")]
        private static extern int DwmExtendFrameIntoClientArea(
            IntPtr hwnd,
            ref Margins pMarInset);

        public static void ExtendFrameIntoClientArea(Window window, int left, int top, int right, int bottom)
        {
            if (Environment.OSVersion.Platform != PlatformID.Win32NT) return;
            if (Environment.OSVersion.Version < new Version(6, 0)) return;

            try
            {
                IntPtr mainWindowPtr = new WindowInteropHelper(window).Handle;
                HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
                if (mainWindowSrc == null) return;

                window.Background = Brushes.Transparent;
                mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0);

                System.Drawing.Graphics desktop = System.Drawing.Graphics.FromHwnd(mainWindowPtr);

                Margins margins = new Margins
                {
                    cxLeftWidth = (int)(left * desktop.DpiX / 96),
                    cxRightWidth = (int)(right * desktop.DpiX / 96),
                    cyTopHeight = (int)(top * desktop.DpiY / 96),
                    cyBottomHeight = (int)(bottom * desktop.DpiY / 96)
                };

                int hr = DwmExtendFrameIntoClientArea(mainWindowSrc.Handle, ref margins);
                if (hr < 0)
                {
                    Debug.WriteLine("DwmExtendFrameIntoClientArea < 0");
                }
            }
            catch (DllNotFoundException ex)
            {
                Debug.WriteLine(ex);
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct DwmBlurBehind
        {
            public DwmBb dwFlags;
            public bool fEnable;
            public IntPtr hRgnBlur;
            public bool fTransitionOnMaximized;
        }

        [Flags]
        private enum DwmBb
        {
            Enable = 1,
            BlurRegion = 2,
            TransitionMaximized = 4
        }

        [DllImport("DwmApi.dll")]
        private static extern int DwmEnableBlurBehindWindow(
                    IntPtr hWnd, ref DwmBlurBehind pBlurBehind);

        public static void EnableBlurBehindWindow(Window window)
        {
            if (Environment.OSVersion.Platform != PlatformID.Win32NT) return;
            if (Environment.OSVersion.Version < new Version(6, 0)) return;

            try
            {
                IntPtr mainWindowPtr = new WindowInteropHelper(window).Handle;
                HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
                if (mainWindowSrc == null) return;

                window.Background = Brushes.Transparent;
                mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0);

                DwmBlurBehind dbb;
                dbb.fEnable = true;
                dbb.dwFlags = DwmBb.Enable;
                dbb.hRgnBlur = IntPtr.Zero;
                dbb.fTransitionOnMaximized = false;

                int hr = DwmEnableBlurBehindWindow(mainWindowSrc.Handle, ref dbb);
                if (hr < 0)
                {
                    Debug.WriteLine("DwmExtendFrameIntoClientArea < 0");
                }
            }
            catch (DllNotFoundException ex)
            {
                Debug.WriteLine(ex);
            }
        }
    }
}